/********************************************************
 *
 * FILE NAME:   signalprocessing.h
 *
 * DESCRIPTION:
 *  Module with signal processing primitives
 *
 ********************************************************/

#ifndef SIGNALPROCESSING_H
#define SIGNALPROCESSING_H

/********************************************************/
/*              Includes                                */
/********************************************************/
#include <QDebug>
#include <QObject>
#include <cstddef>
#include <cmath>

/********************************************************/
/*              Defines                                 */
/********************************************************/

/********************************************************/
/*              Macros                                  */
/********************************************************/
#define EXPORT_SIGNAL(signalPtr, signalName) \
    void * get##signalName() \
    { \
        return (signalPtr); \
    }

/********************************************************/
/*              Typedefs                                */
/********************************************************/
typedef double sample_t;
class ISignal;
class OSignal;
class SignalConnection;

class ISignal
{
    friend class OSignal;
    friend class SignalConnection;

    /********************************************************/
    /*              Typedefs                                */
    /********************************************************/
    public:

    protected:

    private:

    /********************************************************/
    /*              Functions Declarations                  */
    /********************************************************/
    public:
        /********************************************************
         * Function Name    :   ISignal
         *
         * Description      :   Constructor
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   size_t historyLength = num of previous samples that would be accessible
         *                      size_t burstLength = num of samples that can be requested in burst
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        ISignal(size_t historyLength, size_t burstLength);

        /********************************************************
         * Function Name    :   ~ISignal
         *
         * Description      :   Destructor
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        ~ISignal();

        /********************************************************
         * Function Name    :   isConnected
         *
         * Description      :   Check if signal is connected to another signal
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:   true if it is, else false
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        bool isConnected();

        size_t burstLength();

        /********************************************************
         * Function Name    :   operator[]
         *
         * Description      :   Operator [] for reading sample of the signal
         *
         * Side effects     :
         *
         * Comment          :   isignal[0] = current sample, isignal[1] = previous sample, ...
         *
         * Parameters       :   size_t index = index of the sample
         *
         * Returns      	:   constant reference to the sample
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        const sample_t & operator[](size_t index) const;

        /********************************************************
         * Function Name    :   requestBurst
         *
         * Description      :   Request new burst of samples
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   size_t burstLength = burst length
         *
         * Returns      	:   true if new burst processed successfully, else false (i.e. there is no new samples)
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        bool requestBurst(size_t burstLength);

        /********************************************************
         * Function Name    :   readInSample
         *
         * Description      :   Read in new sample value
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        void readInSample();

    protected:

    private:

    /********************************************************/
    /*              Variables Declarations                  */
    /********************************************************/
    public:

    protected:

    private:
        size_t _historyLength;
        size_t _burstLength;

        sample_t *_data;
        size_t _dataSize;
        size_t _dataStart;

        OSignal *_connectedTo;

};
class OSignal
{
    friend class ISignal;
    friend class SignalConnection;

    /********************************************************/
    /*              Typedefs                                */
    /********************************************************/
    public:

    protected:

    private:

    /********************************************************/
    /*              Functions Declarations                  */
    /********************************************************/
    public:
        /********************************************************
         * Function Name    :   OSignal
         *
         * Description      :   Constructor
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   size_t historyLength = num of previous samples that would be accessible
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        OSignal(size_t historyLength);

        /********************************************************
         * Function Name    :   ~OSignal
         *
         * Description      :   Destructor
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        virtual ~OSignal();

        /********************************************************
         * Function Name    :   isConnected
         *
         * Description      :   Check if signal is connected to another signal
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:   true if it is, else false
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        bool isConnected();

        size_t burstLength();

    protected:
        /********************************************************
         * Function Name    :   operator[]
         *
         * Description      :   Operator [] for reading/writing sample of the signal
         *
         * Side effects     :
         *
         * Comment          :   osignal[0] = current sample, osignal[1] = previous sample, ...
         *
         * Parameters       :   size_t index = index of the sample
         *
         * Returns      	:   reference to the sample
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        sample_t & operator[](size_t index);

        /********************************************************
         * Function Name    :   onBurstRequest
         *
         * Description      :   Called when new burst of samples requested
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   size_t burstLength = burst length
         *
         * Returns      	:   true if burst of samples successfully processed, else false
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        virtual bool onBurstRequest(size_t burstLength) = 0;

        /********************************************************
         * Function Name    :   writeOutSample
         *
         * Description      :   Write out current sample value
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        void writeOutSample();

    private:

    /********************************************************/
    /*              Variables Declarations                  */
    /********************************************************/
    public:

    protected:

    private:
        size_t _historyLength;

        sample_t *_data;
        size_t _dataSize;
        size_t _dataStart;

        ISignal *_connectedTo;

};
class SignalConnection : public QObject
{
    Q_OBJECT

    /********************************************************/
    /*              Typedefs                                */
    /********************************************************/
    public:

    protected:

    private:

    /********************************************************/
    /*              Functions Declarations                  */
    /********************************************************/
    public:
        /********************************************************
         * Function Name    :   SignalConnection
         *
         * Description      :   Constructor
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   QObject *parent = Qt Object parent of the SignalConnection object
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com
         *
         ********************************************************/
        SignalConnection(QObject *parent = 0);

        /********************************************************
         * Function Name    :   registerTypes
         *
         * Description      :   Register SignalConnection class to QML
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :
         *
         * Returns      	:
         *
         * Reviewed by      :   v_duschan@hotmail.com
         *
         ********************************************************/
        static void registerTypes(const char *uri);

        /********************************************************
         * Function Name    :   connect
         *
         * Description      :   Connect output (OSignal) and input (ISignal) signals
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   OSignal *out = pointer to output signal
         *                      ISignal *in = pointer to input signal
         *
         * Returns      	:   true if successfully connected, else false
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        static bool connect(OSignal *out, ISignal *in);

        /********************************************************
         * Function Name    :   connect
         *
         * Description      :   Connect output (OSignal) and input (ISignal) signals
         *
         * Side effects     :
         *
         * Comment          :
         *
         * Parameters       :   void *out = pointer to output signal
         *                      void *in = pointer to input signal
         *
         * Returns      	:   true if successfully connected, else false
         *
         * Reviewed by      :   v_duschan@hotmail.com, draganmarjanovic10@gmail.com
         *
         ********************************************************/
        Q_INVOKABLE static bool connect(void *out, void *in);

    protected:

    private:

    /********************************************************/
    /*              Variables Declarations                  */
    /********************************************************/
    public:

    protected:

    private:

};

/********************************************************/
/*              Functions Declarations                  */
/********************************************************/

/********************************************************/
/*              Variables Declarations (IMPORT)         */
/********************************************************/

#endif /* SIGNALPROCESSING_H */
